﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
using nanoCMS.Core.Concrete;

namespace nanoCMS.Core.Providers {
	public class TenantProvider {
		private Entities entities;
		private const string TenantCacheKey = "TenantData";
		private const string TenantHostnameCacheKey = "TenantHostnamesData";


		public TenantProvider(Entities entities) {
			this.entities = entities;
		}

		private CacheProvider cacheProvider = CacheProvider.Default;

		public Tenant Add(string name, string description = null, string comment = null, string url = null) {
			//TODO: add element to pageTemplates
			//TODO: add to cache

			Tenant tenant = new Tenant {
				Name = name,
				Description = description,
				Comment = comment
			};
			entities.Tenants.AddObject(tenant);
			entities.SaveChanges();
			return tenant;
		}

		public Tenant Get(int id) {

			if (!cacheProvider.Contains(TenantCacheKey))
			{
				cacheProvider.Add(TenantCacheKey, entities.Tenants.ToList());
			}

			List<Tenant> tenantsCache = cacheProvider.Get(TenantCacheKey) as List<Tenant>;
			if (!tenantsCache.Any(x=>x.TenantID == id))
			{
				Tenant dbData = entities.Tenants.SingleOrDefault(x => x.TenantID == id);
				if (dbData == null) throw  new ArgumentOutOfRangeException(id.ToString(), "No tenant with argument value");

				tenantsCache.Add(dbData);
				cacheProvider.Add(TenantCacheKey, tenantsCache);

				return dbData;
			}

			return tenantsCache.SingleOrDefault(x => x.TenantID == id);
		}



		public int GetTenantID(string url) {
			Uri uri = new Uri(url);
			url = uri.GetLeftPart(UriPartial.Path);
			if (uri.IsAbsoluteUri)
			{
				url = url.Remove(0, uri.GetLeftPart(UriPartial.Scheme).Length);
			}

			List<TenantHostname> tenantHostnames = new List<TenantHostname>();

			if (!cacheProvider.Contains(TenantHostnameCacheKey))
			{
				var data = entities.TenantHostnames.ToList();
				if (data.Count == 0) throw new Exception("No tenant hostname data");
				cacheProvider.Add(TenantHostnameCacheKey, data);
			}
			tenantHostnames = cacheProvider.Get(TenantHostnameCacheKey) as List<TenantHostname>;
			if (tenantHostnames == null) throw new Exception("tenantHostnames is null");

			string urlLeftPart = String.Empty;
			
			foreach (var component in url.Split('/'))
			{
				urlLeftPart += component;
				if (tenantHostnames.Any(x=>x.Url == urlLeftPart))
				{
					return tenantHostnames.SingleOrDefault(x => x.Url == urlLeftPart).TenantID;
				}
				urlLeftPart += "/";
			}
			throw new Exception("Non existant tenant");
		}

		//TODO: edit

	}
}
